from machine import Pin
from machine import Timer
from time import sleep_ms
import ubluetooth
import usocket
import ujson
import machine
import time
import rgb
import buzzer
import os
import _thread


class ESP32_BLE:
    '''
    蓝牙属性
    '''
    bule_flag = 0  # 蓝牙连接标志位
    motor_flag = 0  # 电机蓝牙控制标志位
    motor_go = 0  # 电机前进速度
    motor_back = 0  # 电机后退速度
    max_speed = 255  # 最大运行速度 80-255
    buzzeropen = 1  # 开机自启动音效
    buzzerblue = 1  # 蓝牙连接音效

    def __init__(
        self,
        name,
        rgb,
        buzzer,
    ):
        self.name = name
        self.rgb = rgb
        self.buzzer = buzzer
        self.ble = ubluetooth.BLE()
        self.ble.active(True)
        self.ble.config(gap_name=name)
        self.disconnected()
        self.ble.irq(self.ble_irq)
        self.register()
        self.advertiser()
        self.connected_send_info = "lv-box-0001-white"      # 初次连接设备信息反馈
        self.ota_file = {
            "main": 0,
            "rgb": 0,
            "ble": 0,
            "handgrip": 0,
            "buzzer": 0,
            "pid": 0,
            "pwm": 0,
        }  # 蓝牙OTA文件

        self.ble_processing = {
            "rgb": self.RGB_Change,
            "info": self.BLE_INFO,
            "light": self.RGB_Llight,
            "Rgbmode": self.RGB_Mode,
            "go": self.BLE_Control,
            "max": self.Speed_Limit,
            "buzzer": self.Buzzer_Control,
            "remove": self.Remove_Attribute,
            "grip": self.Get_Grip_Samping,
            "ota": self.OTA_Uptae,
            "wifi": self.Boot_Get_Wifi,
        }  # 蓝牙中断进程处理

        self.wifi_file = {
            "wifiname": "lvshun",
            "wifipass": "lvshun123",
        }
# ============================================================================== #

    """
    蓝牙断开连接的函数
    """

    def disconnected(self):
        pass

# ============================================================================== #

    """
    蓝牙中断服务函数
    """

    def ble_irq(self, event, data):
        global bule_flag
        if event == 1:  # _IRQ_CENTRAL_CONNECT 手机链接了此设备
            print("蓝牙已连接")
            if self.buzzerblue == 1:  # 蓝牙连接音效
                _thread.start_new_thread(self.buzzer.Buzzer_Play, ("bleopen",))
            ESP32_BLE.bule_flag = 1
            time.sleep_ms(100)
            self.send(self.connected_send_info)  # 发送设备编号和颜色
            time.sleep_ms(100)
            self.send(self.connected_send_info)  # 发送设备编号和颜色
            # device_base_info= "lvi"+"-"+str(self.rgb.mode)+"-"+str(self.max_speed)+"-"+str(self.buzzeropen)+"-"+str(self.buzzerblue)+"-" # 设备已设置的限速和响铃信息返回上位机，示例格式lvi-gradient-255-1-1-
            # self.send(device_base_info) # 发送设备状态信息
        elif event == 2:  # _IRQ_CENTRAL_DISCONNECT 手机断开此设备
            self.advertiser()
            self.disconnected()
            print("蓝牙已断开")
            if self.buzzerblue == 1:  # 蓝牙断开音效
                _thread.start_new_thread(
                    self.buzzer.Buzzer_Play, ("bleclose",))
            ESP32_BLE.motor_flag = 0
            ESP32_BLE.bule_flag = 0
        elif event == 3:  # _IRQ_GATTS_WRITE 手机发送了数据
            buffer = self.ble.gatts_read(self.rx)
            BLE_MSG = buffer.decode("UTF-8").strip()
            print("Received data:", BLE_MSG)
            self.ble_processing.get(BLE_MSG.split(
                "+")[0], self.Default_Rev_Date)(BLE_MSG)
            time.sleep_ms(100)

# ============================================================================== #

    """
    蓝牙服务注册
    """

    def register(self):
        service_uuid = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E"
        reader_uuid = "6E400002-B5A3-F393-E0A9-E50E24DCCA9E"
        sender_uuid = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E"

        services = (
            (
                ubluetooth.UUID(service_uuid),
                (
                    (ubluetooth.UUID(sender_uuid), ubluetooth.FLAG_NOTIFY),
                    (ubluetooth.UUID(reader_uuid), ubluetooth.FLAG_WRITE),
                ),
            ),
        )

        (
            (
                self.tx,
                self.rx,
            ),
        ) = self.ble.gatts_register_services(services)


# ============================================================================== #

    """
    蓝牙发送信息
    """

    def send(self, data):
        self.ble.gatts_notify(0, self.tx, data + "\n")

# ============================================================================== #

    """
    蓝牙发送信息
    """

    def advertiser(self):
        name = bytes(self.name, "UTF-8")
        adv_data = bytearray("\x02\x01\x02", "UTF-8") + \
            bytearray((len(name) + 1, 0x09), "UTF-8") + name
        self.ble.gap_advertise(100, adv_data)
        print(adv_data)
        print("\r\n")

# ============================================================================== #

    """
    往Flash的RGB文件写入数据
    """

    def Setting_flash_Rgb(self):
        data = {
            "rgb_mode_flash_data": self.rgb.mode,
            "rgb_light_flash_data": self.rgb.light,
            "rgb_speed_flash_data": self.rgb.light_speed,
            "rgb_R_flash_data": self.rgb.R,
            "rgb_G_flash_data": self.rgb.G,
            "rgb_B_flash_data": self.rgb.B,
        }
        # 将数据转换为JSON格式
        json_data = ujson.dumps(data)
        # 已完成初次采样 标志位写入Flash
        try:
            with open("flash_rgb_data.json", "w") as f:
                f.write(json_data)
        except Exception as e:
            print("*****Setting_flash_Rgb error*****", e)

# ============================================================================== #

    """
    往Flash中写入限速数据文件
    """

    def Setting_flash_Speed(self):
        data = {
            "max_speed_flash_data": self.max_speed,
        }
        # 将数据转换为JSON格式
        json_data = ujson.dumps(data)
        # 已完成初次采样 标志位写入Flash
        try:
            with open("max_speed_flash_data.json", "w") as f:
                f.write(json_data)
        except Exception as e:
            print("*****Setting_flash_Speed error*****", e)

# ============================================================================== #

    """
    往Flash中写入蜂鸣器数据文件
    """

    def Setting_flash_Buzzer(self):
        data = {
            "buzzer_open_data": self.buzzeropen,
            "buzzer_blue_data": self.buzzerblue,
        }
        # 将数据转换为JSON格式
        json_data = ujson.dumps(data)
        # 已完成初次采样 标志位写入Flash
        try:
            with open("buzzer_flash_data.json", "w") as f:
                f.write(json_data)
        except Exception as e:
            print("*****Setting_flash_Buzzer error*****", e)

# ============================================================================== #

    """
    清除握把值文件并重启main函数重新采样
    """

    def Remove_flash_Handgrip(self):
        try:
            file_names = ["flash_data.txt", "flash_data.json"]
            for file_name in file_names:
                if file_name in os.listdir():
                    os.remove(file_name)
            # 等待5秒钟
            time.sleep(3)
            machine.reset()
        except Exception as e:
            print("*****Remove_flash_Handgrip error*****", e)

# ============================================================================== #

    """
    远程程ota时给boot标志
    """

    def Ota_Boot_flash(self):
        data = {
            "Ota_main": self.ota_file["main"],
            "Ota_rgb": self.ota_file["rgb"],
            "Ota_ble": self.ota_file["ble"],
            "Ota_handgrip": self.ota_file["handgrip"],
            "Ota_buzzer": self.ota_file["buzzer"],
            "Ota_pid": self.ota_file["pid"],
            "Ota_pwm": self.ota_file["pwm"],
        }
        # 将数据转换为JSON格式
        json_data = ujson.dumps(data)
        # 已完成初次采样 标志位写入Flash
        try:
            with open("Ota_Boot_flash.json", "w") as f:
                f.write(json_data)
            # 等待5秒钟
            time.sleep(3)
            machine.reset()
        except Exception as e:
            print("*****Ota_Boot_flash error*****", e)

# ============================================================================== #

    """
    RGB的数据修改，RGB的类数据修改以及往FLASH写入RGB数据
    """

    def RGB_Change(self, ble_msg):
        rgb_values = ble_msg.split("+")  # 保存"rgb+"后面的值到变量rgb_values
        r = int(rgb_values[1])
        g = int(rgb_values[2])
        b = int(rgb_values[3])
        l = int(rgb_values[4])
        self.rgb.R = r
        self.rgb.G = g
        self.rgb.B = b
        self.rgb.light = l
        self.rgb.last_light = self.rgb.light
        self.rgb.mode = "stop"
        self.rgb.RGB_Write_Data()
        self.Setting_flash_Rgb()  # 保存灯光设置

# ============================================================================== #

    """
    蓝牙发送INFO数据
    """

    def BLE_INFO(self, ble_msg):
        time.sleep_ms(100)
        # print("resend info working")
        self.send(self.connected_send_info)

# ============================================================================== #

    """
    RGB灯亮度修改，0 - 200
    """

    def RGB_Llight(self, ble_msg):
        rgb_light = ble_msg.split("+")
        l = int(rgb_light[1])
        l = min(200, l)
        self.rgb.light = l
        self.rgb.last_light = self.rgb.light
        print("RGB light:", self.rgb.light)
        self.rgb.RGB_Write_Data()
        self.Setting_flash_Rgb()  # 保存灯光设置

# ============================================================================== #

    """
    RGB灯的模式切换，以及灯效速度改变， 0 - 899
    """

    def RGB_Mode(self, ble_msg):
        rgb_mode = ble_msg.split("+")  # 保存"Rgbmode+"后面的值到变量rgb_mode
        if str(rgb_mode[1]) != "speedset":
            self.rgb.mode = str(rgb_mode[1])
            print(rgb_mode[1])
        elif str(rgb_mode[1]) == "speedset":
            self.rgb.light_speed = int(rgb_mode[2])
            print(rgb_mode[1])
        self.Setting_flash_Rgb()  # 保存灯光设置

# ============================================================================== #

    """
    蓝牙控制电机运行
    """

    def BLE_Control(self, ble_msg):
        self.motor_flag = int(1)
        speed_temp = ble_msg.split("+")  # 蓝牙控制速度数据
        self.motor_go = int(speed_temp[1])
        self.motor_back = int(speed_temp[2])

# ============================================================================== #

    """
    电机最大速度的限制， 80 - 255
    """

    def Speed_Limit(self, ble_msg):
        max_temp = ble_msg.split("+")  # 限速数据
        self.max_speed = int(str(max_temp[1]))
        self.max_speed = max(80, self.max_speed)
        print("Limit Speed:", self.max_speed)
        self.Setting_flash_Speed()  # 保存限速设置

# ============================================================================== #

    """
    蜂鸣器的音效切换，以及灯效在开机或者连接蓝牙时是否开启
    """

    def Buzzer_Control(self, ble_msg):
        buzzer_flag = ble_msg.split("+")  # 响铃数据
        if str(buzzer_flag[1]) == "set":
            if str(buzzer_flag[2]) == "open":
                if int(buzzer_flag[3]) == 0:
                    self.buzzeropen = int(0)
                    self.Setting_flash_Buzzer()
                elif int(buzzer_flag[3]) == 1:
                    self.buzzeropen = int(1)
                    self.Setting_flash_Buzzer()
            elif str(buzzer_flag[2]) == "blue":
                if int(buzzer_flag[3]) == 0:
                    self.buzzerblue = int(0)
                    self.Setting_flash_Buzzer()
                elif int(buzzer_flag[3]) == 1:
                    self.buzzerblue = int(1)
                    self.Setting_flash_Buzzer()
        elif str(buzzer_flag[1]) == "task":
            if int(buzzer_flag[2]) == 1:
                _thread.start_new_thread(self.buzzer.Buzzer_Play, ("task1",))
            elif int(buzzer_flag[2]) == 2:
                _thread.start_new_thread(self.buzzer.Buzzer_Play, ("task2",))
            elif int(buzzer_flag[2]) == 3:
                _thread.start_new_thread(self.buzzer.Buzzer_Play, ("task3",))

# ============================================================================== #

    """
    重采握把值
    """

    def Remove_Attribute(self, ble_msg):
        remove_flag = ble_msg.split("+")
        if str(remove_flag[1]) == "hand":      # 握把重新采样
            self.Remove_flash_Handgrip()

# ============================================================================== #

    """
    获取握把值
    """

    def Get_Grip_Samping(self, ble_msg):
        pass

# ============================================================================== #

    """
    远程OTA
    """

    def OTA_Uptae(self, ble_msg):
        ota_fields = ble_msg.split("+")
        # 去除开头的 "ota" 字符串
        ota_fields = ota_fields[1:]
        if len(ota_fields) == 8:  # 检查 ota_flag 是否包含足够的字段
            # 解析 OTA 数据并赋值给 ota_file
            self.ota_file["main"] = int(ota_fields[0])
            self.ota_file["rgb"] = int(ota_fields[1])
            self.ota_file["ble"] = int(ota_fields[2])
            self.ota_file["handgrip"] = int(ota_fields[3])
            self.ota_file["buzzer"] = int(ota_fields[4])
            self.ota_file["pid"] = int(ota_fields[5])
            self.ota_file["pwm"] = int(ota_fields[6])
            # 打印成功消息或进行其他操作
            print("OTA 数据格式正确！")
            _thread.start_new_thread(self.buzzer.Buzzer_Play, ("buzzer1",))
            self.Ota_Boot_flash()
        else:
            print("OTA 数据格式错误！")


# ============================================================================== #

    """
    接收到wifi名称和密码，并写入flash中
    """

    def Boot_Get_Wifi(self, ble_msg):
        wifi_fields = ble_msg.split("+")
        if str(wifi_fields[1]) == "n":
            self.wifi_file["wifiname"] = str(wifi_fields[2])
        if str(wifi_fields[1]) == "p":
            self.wifi_file["wifipass"] = str(wifi_fields[2])
        data = {
            "Wifi_name": self.wifi_file["wifiname"],
            "Wifi_pass": self.wifi_file["wifipass"],
        }
        # 将数据转换为JSON格式
        json_data = ujson.dumps(data)
        # 已完成初次采样 标志位写入Flash
        try:
            with open("Wifi_flash_data.json", "w") as f:
                f.write(json_data)
        except Exception as e:
            print("*****Ota_Boot_flash error*****", e)

    def Default_Rev_Date(self, ble_msg):
        print(ble_msg)
